home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / ppm / yuvtoppm.c < prev   
Encoding:
C/C++ Source or Header  |  1991-12-10  |  2.6 KB  |  102 lines

  1. /* yuvtoppm.c - convert Abekas YUV bytes into a portable pixmap
  2. **
  3. ** by Marc Boucher
  4. ** Internet: marc@PostImage.COM
  5. ** 
  6. ** Based on Example Conversion Program, A60/A64 Digital Video Interface
  7. ** Manual, page 69
  8. **
  9. ** Uses integer arithmetic rather than floating point for better performance
  10. **
  11. ** Copyright (C) 1991 by DHD PostImage Inc.
  12. ** Copyright (C) 1987 by Abekas Video Systems Inc.
  13. ** Copyright (C) 1991 by Jef Poskanzer.
  14. **
  15. ** Permission to use, copy, modify, and distribute this software and its
  16. ** documentation for any purpose and without fee is hereby granted, provided
  17. ** that the above copyright notice appear in all copies and that both that
  18. ** copyright notice and this permission notice appear in supporting
  19. ** documentation.  This software is provided "as is" without express or
  20. ** implied warranty.
  21. */
  22.  
  23. #include "ppm.h"
  24.  
  25. /* x must be signed for the following to work correctly */
  26. #define limit(x) (((x>0xffffff)?0xff0000:((x<=0xffff)?0:x&0xff0000))>>16)
  27.  
  28. void
  29. main(argc, argv)
  30.     char          **argv;
  31. {
  32.     FILE           *ifp;
  33.     pixel          *pixrow;
  34.     int             argn, rows, cols, row, i;
  35.     char           *usage = "<width> <height> [yuvfile]";
  36.     long  *yuvbuf;
  37.  
  38.     ppm_init(&argc, argv);
  39.  
  40.     argn = 1;
  41.  
  42.     if (argn + 2 > argc)
  43.         pm_usage(usage);
  44.  
  45.     cols = atoi(argv[argn++]);
  46.     rows = atoi(argv[argn++]);
  47.     if (cols <= 0 || rows <= 0)
  48.         pm_usage(usage);
  49.  
  50.     if (argn < argc) {
  51.         ifp = pm_openr(argv[argn]);
  52.         ++argn;
  53.     } else
  54.         ifp = stdin;
  55.  
  56.     if (argn != argc)
  57.         pm_usage(usage);
  58.  
  59.     if (255 > PGM_MAXMAXVAL)
  60.         pm_error(
  61.       "maxval of 255 is too large - try recompiling with a larger pixval type");
  62.  
  63.     ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
  64.     pixrow = ppm_allocrow(cols);
  65.     yuvbuf = (long *) pm_allocrow(cols, 2);
  66.  
  67.     for (row = 0; row < rows; ++row) {
  68.         long   tmp, y, u, v, y1, r, g, b, *yuvptr;
  69.         register pixel *pP;
  70.         register int    col;
  71.  
  72.         fread(yuvbuf, cols * 2, 1, ifp);
  73.  
  74.         for (col = 0, pP = pixrow, yuvptr = yuvbuf; col < cols; col += 2) {
  75.             tmp = *yuvptr++;
  76.             u = (0xff & (tmp >> 24)) - 128;
  77.             y = ((0xff & (tmp >> 16)) - 16);
  78.             if (y < 0) y = 0;
  79.  
  80.             v = (0xff & (tmp >> 8)) - 128;
  81.             y1 = ((0xff & tmp) - 16);
  82.             if (y1 < 0) y1 = 0;
  83.  
  84.             r = 104635 * v;
  85.             g = -25690 * u + -53294 * v;
  86.             b = 132278 * u;
  87.  
  88.             y*=76310; y1*=76310;
  89.  
  90.             PPM_ASSIGN(*pP, limit(r+y), limit(g+y), limit(b+y));
  91.             pP++;
  92.             PPM_ASSIGN(*pP, limit(r+y1), limit(g+y1), limit(b+y1));
  93.             pP++;
  94.         }
  95.         ppm_writeppmrow(stdout, pixrow, cols, (pixval) 255, 0);
  96.     }
  97.     pm_close(ifp);
  98.     pm_close(stdout);
  99.  
  100.     exit(0);
  101. }
  102.